package com.alibaba.citrus.ots.sales.plan.facade.service.salesplan.audit;

import com.alibaba.citrus.ots.common.util.SpringContextUtil;
import com.alibaba.citrus.ots.sales.plan.api.salesplan.SalesPlanQueryService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.OrganizationSelectRequest;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.auditsetting.dto.*;
import com.epoch.app.bcots.auditsetting.model.AuditSetting;
import com.epoch.app.bcots.auditsetting.service.AuditSettingService;
import com.epoch.app.bcots.auditsettingdetail.model.AuditSettingDetail;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.bcots.model.dto.*;
import com.epoch.app.bcots.model.enums.AuditSettingStatusEnum;
import com.epoch.app.bcots.model.enums.AuditSettingTypeEnum;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.bcots.service.BcOtsService;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class AuditSettingServiceImpl implements AuditSettingService {

    private final Log log = Log.getLogger(AuditSettingServiceImpl.class);

    @Resource
    private BcOtsService bcOtsService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private SalesPlanQueryService salesPlanQueryService;

    private static final int ZERO = 0;
    private static final int ONE = 1;

    public Result<List<AuditSettingResponse>> pageQueryAuditSetting(AuditSettingRequest auditSettingRequest) {
        try {
            log.info("BcOtsConstants.SALES_PLAN_REPORT_SWITCH={}", JSONObject.toJSONString(BcOtsConstants.SALES_PLAN_REPORT_SWITCH()));
        } catch (Exception e) {
            log.info("BcOtsConstants.SALES_PLAN_REPORT_SWITCH={}", e);
        }
        log.info("AuditSettingService.pageQueryAuditSetting.request={}", JSONObject.toJSONString(auditSettingRequest));
        if (StringUtils.isEmpty(auditSettingRequest.getOrgBusinessUnitCode())) {
            List<String> orgBusinessUnitCodeList = getOrgBusinessUnitCodeList();
            if (CollectionUtils.isEmpty(orgBusinessUnitCodeList)) {
                return Result.fail("OTS-02-003-01-15-011", ErrorMessage.code("OTS-02-003-01-15-011", null).getDisplayErrorMessage());
            }
            auditSettingRequest.setOrgBusinessUnitCodeList(orgBusinessUnitCodeList);
        }
        AuditSettingLoadListRequest request = convertRequest(auditSettingRequest);
        log.info("AuditSettingService.loadList.request={}", JSONObject.toJSONString(request));
        Result<List<AuditSetting>> result = loadList(request);
        if (!result.isSuccess()) {
            return Result.fail("OTS-02-003-01-16-025", ErrorMessage.code("OTS-02-003-01-16-025", null).getDisplayErrorMessage());
        }
        if (CollectionUtils.isEmpty(result.getResult())) {
            return Result.success(Lists.newArrayList());
        }
        log.info("AuditSettingService.loadList.result={}", JSONObject.toJSONString(result));
        return Result.listSuccess(convertResponseList(result.getResult()), result.getTotal());
    }

    public Result<String> createAuditSetting(CreateAuditSettingRequest createAuditSettingRequest) {
        log.info("AuditSettingService.createAuditSetting.request={}", JSONObject.toJSONString(createAuditSettingRequest));
        if (StringUtils.isEmpty(createAuditSettingRequest.getOrgBusinessUnitCode())) {
            return Result.fail("OTS-02-003-01-15-008", ErrorMessage.code("OTS-02-003-01-15-008", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(createAuditSettingRequest.getType())) {
            return Result.fail("OTS-02-003-01-15-009", ErrorMessage.code("OTS-02-003-01-15-009", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(createAuditSettingRequest.getOrgChannelCode())) {
            return Result.fail("OTS-02-003-01-15-016", ErrorMessage.code("OTS-02-003-01-15-016", null).getDisplayErrorMessage());
        }
        //校验业务单元+审批业务类型+销售渠道唯一
        Result<Boolean> check = checkRepeatAuditSetting(createAuditSettingRequest.getOrgBusinessUnitCode(), createAuditSettingRequest.getType(), createAuditSettingRequest.getOrgChannelCode());
        if (!check.isSuccess()) {
            return Result.fail(check.getErrorCode(), check.getMessage());
        }
        EmployeeGetCurrentLoginResponse loginResponse = bcOtsService.employeeGetCurrentLogin();
        if (!loginResponse.getSuccess()) {
            log.info("获取登录人信息失败AuditSettingService.createAuditSetting.employeeGetCurrentLoginResponse={}", JSONObject.toJSONString(loginResponse));
        }
        CreateAuditSettingRequest auditSettingRequest = new CreateAuditSettingRequest();
        auditSettingRequest.setOrgBusinessUnitCode(createAuditSettingRequest.getOrgBusinessUnitCode());
        auditSettingRequest.setType(createAuditSettingRequest.getType());
        auditSettingRequest.setOrgChannelCode(createAuditSettingRequest.getOrgChannelCode());
        auditSettingRequest.setStatus(null == createAuditSettingRequest.getStatus() ? AuditSettingStatusEnum.ENABLE.getType() : createAuditSettingRequest.getStatus());
        auditSettingRequest.setGmtCreate(new Date());
        auditSettingRequest.setGmtModified(new Date());
        auditSettingRequest.setCreator(loginResponse.getEmployeeId());
        auditSettingRequest.setUpdater(loginResponse.getEmployeeId());
        auditSettingRequest.setVersion(ZERO);
        CreateResponse createResponse = null;
        try {
            createResponse = create(auditSettingRequest);
            if (StringUtils.isEmpty(createResponse.getId())) {
                return Result.fail("OTS-02-003-01-16-022", ErrorMessage.code("OTS-02-003-01-16-022", null).getDisplayErrorMessage());
            }
        } catch (Exception e) {
            log.info("审批配置创建失败={}", e);
            return Result.fail("OTS-02-003-01-16-029", ErrorMessage.code("OTS-02-003-01-16-029", null).getDisplayErrorMessage());
        }
        return Result.success(createResponse.getId());
    }

    public Result<Boolean> deleteAuditSetting(DeleteAuditSettingRequest deleteAuditSettingRequest) {
        log.info("AuditSettingService.deleteAuditSetting.request={}", JSONObject.toJSONString(deleteAuditSettingRequest));
        if (null == deleteAuditSettingRequest.getId()) {
            return Result.fail("OTS-02-003-01-15-010", ErrorMessage.code("OTS-02-003-01-15-010", null).getDisplayErrorMessage());
        }
        try {
            AuditSetting auditSetting = load1(Load1Request.builder().id(deleteAuditSettingRequest.getId()).build());
            if (null == auditSetting) {
                return Result.fail("OTS-02-003-01-16-023", ErrorMessage.code("OTS-02-003-01-16-023", null).getDisplayErrorMessage());
            }
            DeleteResponse deleteResponse = delete(DeleteRequest.builder().id(deleteAuditSettingRequest.getId()).build());
            if (deleteResponse.getCount() != ONE) {
                return Result.fail("OTS-02-003-01-16-024", ErrorMessage.code("OTS-02-003-01-16-024", null).getDisplayErrorMessage());
            }
            return Result.success(true);
        } catch (Exception e) {
            log.info("审批配置删除失败={}", e);
            return Result.fail("OTS-02-003-01-16-024", ErrorMessage.code("OTS-02-003-01-16-024", null).getDisplayErrorMessage());
        }
    }

    public Result<AuditSettingResponse> queryAuditSettingById(QueryAuditSettingByIdRequest queryAuditSettingByIdRequest) {
        log.info("AuditSettingService.queryAuditSettingById.request={}", JSONObject.toJSONString(queryAuditSettingByIdRequest));
        if (null == queryAuditSettingByIdRequest.getId()) {
            return Result.fail("OTS-02-003-01-15-010", ErrorMessage.code("OTS-02-003-01-15-010", null).getDisplayErrorMessage());
        }
        AuditSetting auditSetting = load1(Load1Request.builder().id(queryAuditSettingByIdRequest.getId()).build());
        if (null == auditSetting) {
            return Result.fail("OTS-02-003-01-16-026", ErrorMessage.code("OTS-02-003-01-16-026", null).getDisplayErrorMessage());
        }
        //查询组织
        Set<String> organizationIds = Sets.newHashSet(auditSetting.getOrgBusinessUnitCode(), auditSetting.getOrgChannelCode());
        Map<String, String> organizationSDOMap = getOrganizationSDOMap(organizationIds);
        //查询员工
        Set<String> employeeIds = Sets.newHashSet(auditSetting.getCreator(), auditSetting.getUpdater());
        Map<String, String> employeeSDOMap = getEmployeeSDOMap(employeeIds);
        log.info("queryAuditSettingById.organizationSDOMap={}", JSONObject.toJSONString(organizationSDOMap));
        log.info("queryAuditSettingById.employeeSDOMap={}", JSONObject.toJSONString(employeeSDOMap));

        AuditSettingResponse auditSettingResponse = convertResponse(organizationSDOMap, employeeSDOMap, auditSetting);
        log.info("queryAuditSettingById.auditSettingResponse={}", JSONObject.toJSONString(auditSettingResponse));
        return Result.success(auditSettingResponse);
    }

    public Result<Boolean> editStatus(EditStatusRequest editStatusRequest) {
        log.info("AuditSettingService.editStatus.request={}", JSONObject.toJSONString(editStatusRequest));
        if (null == editStatusRequest.getId()) {
            return Result.fail("OTS-02-003-01-15-010", ErrorMessage.code("OTS-02-003-01-15-010", null).getDisplayErrorMessage());
        }
        AuditSetting auditSetting = load1(Load1Request.builder().id(editStatusRequest.getId()).build());
        if (null == auditSetting) {
            return Result.fail("OTS-02-003-01-16-026", ErrorMessage.code("OTS-02-003-01-16-026", null).getDisplayErrorMessage());
        }
        if (editStatusRequest.getStatusSwitch()) {
            auditSetting.setStatus(AuditSettingStatusEnum.ENABLE.getType());
        } else {
            auditSetting.setStatus(AuditSettingStatusEnum.DISENABLE.getType());
        }
        //获取当前登录员工信息
        try {
            EmployeeGetCurrentLoginResponse loginResponse = bcOtsService.employeeGetCurrentLogin();
            if (!loginResponse.getSuccess()) {
                log.info("获取登录人信息失败AuditSettingService.createAuditSetting.employeeGetCurrentLoginResponse={}", JSONObject.toJSONString(loginResponse));
            }
            auditSetting.setUpdater(loginResponse.getEmployeeId());
        } catch (Exception e) {
            log.info("获取登录人信息失败={}", e);
        }
        auditSetting.setGmtModified(new Date());
        UpdateResponse updateResponse = update(auditSetting);
        if (updateResponse.getCount() != ONE) {
            return Result.fail("OTS-02-003-01-16-027", ErrorMessage.code("OTS-02-003-01-16-027", null).getDisplayErrorMessage());
        }
        return Result.success(true);
    }


    private List<String> getOrgBusinessUnitCodeList() {
        EmployeeGetCurrentLoginResponse loginResponse = bcOtsService.employeeGetCurrentLogin();
        if (!loginResponse.getSuccess()) {
            log.info("获取登录人信息失败AuditSettingService.pageQueryAuditSetting.employeeGetCurrentLoginResponse={}", JSONObject.toJSONString(loginResponse));
            return Lists.newArrayList();
        }
        OrganizationSelectRequest request = new OrganizationSelectRequest();
        request.setEmployeeId(loginResponse.getEmployeeId());
        request.setEmployeeName(loginResponse.getEmployeeName());
        request.setBelongOrganizationId(loginResponse.getBelongOrganizationId());
        request.setRelatedOrganizationId(loginResponse.getRelatedOrganizationId());
        request.setIsSales(loginResponse.getIsSales());
        request.setRelatedOrganizationType(loginResponse.getRelatedOrganizationType());
        Result<List<OrganizationSDO>> result = salesPlanQueryService.organizationSelect(request);
        if (!result.isSuccess() || CollectionUtils.isEmpty(result.getResult())) {
            log.info("获取登录人所属业务单元失败AuditSettingService.pageQueryAuditSetting.organizationSelect={}", JSONObject.toJSONString(result));
            return Lists.newArrayList();
        }
        return result.getResult().stream().map(OrganizationSDO::getId).distinct().collect(Collectors.toList());
    }

    private List<AuditSettingResponse> convertResponseList(List<AuditSetting> auditSettingList) {
        //查询组织
        Set<String> organizationIds = auditSettingList.stream().map(AuditSetting::getOrgBusinessUnitCode).collect(Collectors.toSet());
        organizationIds.addAll(auditSettingList.stream().map(AuditSetting::getOrgChannelCode).collect(Collectors.toSet()));
        Map<String, String> organizationSDOMap = getOrganizationSDOMap(organizationIds);
        //查询员工
        Set<String> employeeIds = auditSettingList.stream().map(AuditSetting::getCreator).collect(Collectors.toSet());
        employeeIds.addAll(auditSettingList.stream().map(AuditSetting::getUpdater).collect(Collectors.toSet()));
        Map<String, String> employeeSDOMap = getEmployeeSDOMap(employeeIds);
        log.info("convertResponseList.organizationSDOMap={}", JSONObject.toJSONString(organizationSDOMap));
        log.info("convertResponseList.employeeSDOMap={}", JSONObject.toJSONString(employeeSDOMap));

        List<AuditSettingResponse> list = new ArrayList<>();
        for (AuditSetting auditSetting : auditSettingList) {
            list.add(convertResponse(organizationSDOMap, employeeSDOMap, auditSetting));
        }
        log.info("convertResponseList.list={}", JSONObject.toJSONString(list));
        return list;
    }

    private Map<String, String> getEmployeeSDOMap(Set<String> employeeIds) {
        Map<String, String> employeeSDOMap = new HashMap<>();
        Result<List<EmployeeSDO>> employeeResult = baseDataService.baselineGetEmployeeByIdsAll(BaselineGetEmployeeByIdsAllRequest.builder()
                .ids(new ArrayList<String>(employeeIds)).build());
        if (!employeeResult.isSuccess() || CollectionUtils.isEmpty(employeeResult.getResult())) {
            log.info("查询员工信息失败AuditSettingService.convertResponseList.employeeIds={}", JSONObject.toJSONString(employeeIds));
        } else {
            employeeSDOMap = employeeResult.getResult().stream().collect(Collectors.toMap(EmployeeSDO::getId, EmployeeSDO::getName, (a, b) -> a));
        }
        return employeeSDOMap;
    }

    private Map<String, String> getOrganizationSDOMap(Set<String> organizationIds) {
        Map<String, String> organizationSDOMap = new HashMap<>();
        BaselineGetOrganizationByIdsAllResponse organizationResult = baseDataService.baselineGetOrganizationByIdsAll(BaselineGetOrganizationByIdsAllRequest.builder()
                .ids(new ArrayList<String>(organizationIds)).build());
        if (!organizationResult.getSuccess() || CollectionUtils.isEmpty(organizationResult.getResult())) {
            log.info("查询组织信息失败AuditSettingService.convertResponseList.ids={}", JSONObject.toJSONString(organizationIds));
        } else {
            organizationSDOMap = organizationResult.getResult().stream().collect(Collectors.toMap(OrganizationSDO::getId, OrganizationSDO::getName, (a, b) -> a));
        }
        return organizationSDOMap;
    }

    private AuditSettingResponse convertResponse(Map<String, String> organizationSDOMap, Map<String, String> employeeSDOMap, AuditSetting auditSetting) {
        AuditSettingResponse auditSettingResponse = new AuditSettingResponse();
        auditSettingResponse.setId(auditSetting.getId());
        auditSettingResponse.setOrgBusinessUnitCode(auditSetting.getOrgBusinessUnitCode());
        auditSettingResponse.setOrgBusinessUnitName(organizationSDOMap.get(auditSetting.getOrgBusinessUnitCode()));
        auditSettingResponse.setOrgChannelCode(auditSetting.getOrgChannelCode());
        auditSettingResponse.setOrgChannelName(organizationSDOMap.get(auditSetting.getOrgChannelCode()));
        auditSettingResponse.setAuditSettingType(auditSetting.getType());
        if (null != AuditSettingTypeEnum.of(auditSetting.getType())) {
            auditSettingResponse.setAuditSettingTypeName(AuditSettingTypeEnum.of(auditSetting.getType()).getDesc());
        }
        auditSettingResponse.setStatus(auditSetting.getStatus());
        auditSettingResponse.setStatusValue(auditSetting.getStatus() == 1);
        StatusSwitch statusSwitch = new StatusSwitch();
        statusSwitch.setText(auditSetting.getStatus() == 1 ? "启用中" : "禁用中");
        statusSwitch.setValue(auditSetting.getStatus() == 1);
        auditSettingResponse.setStatusSwitch(statusSwitch);
        if (null != AuditSettingStatusEnum.of(auditSetting.getStatus())) {
            auditSettingResponse.setStatusDesc(AuditSettingStatusEnum.of(auditSetting.getStatus()).getDesc());
        }
        if (MapUtils.isNotEmpty(employeeSDOMap)) {
            auditSettingResponse.setUpdaterName(employeeSDOMap.get(auditSetting.getUpdater()));
            auditSettingResponse.setCreatorName(employeeSDOMap.get(auditSetting.getCreator()));
        }
        auditSettingResponse.setGmtCreate(auditSetting.getGmtCreate());
        auditSettingResponse.setGmtModified(auditSetting.getGmtModified());
        return auditSettingResponse;
    }

    private AuditSettingLoadListRequest convertRequest(AuditSettingRequest auditSettingRequest) {
        AuditSettingLoadListRequest request = AuditSettingLoadListRequest.newAuditSettingLoadListRequestBuilder().build();
        request.setOrgBusinessUnitCode(auditSettingRequest.getOrgBusinessUnitCode());
        request.setOrgBusinessUnitCodeList(auditSettingRequest.getOrgBusinessUnitCodeList());
        request.setOrgChannelCode(auditSettingRequest.getOrgChannelCode());
        request.setType(auditSettingRequest.getAuditSettingType());
        request.setStatus(auditSettingRequest.getStatus());
        request.setPage(auditSettingRequest.getPage());
        request.setSize(auditSettingRequest.getSize());
        request.setStart(auditSettingRequest.getStart());
        request.setLimit(auditSettingRequest.getLimit());
        return request;
    }

    private Result<Boolean> checkRepeatAuditSetting(String orgBusinessUnitCode, String type, String orgChannelCode) {
        Result<List<AuditSetting>> resultList = loadList(AuditSettingLoadListRequest.newAuditSettingLoadListRequestBuilder()
                .orgBusinessUnitCode(orgBusinessUnitCode).type(type).orgChannelCode(orgChannelCode).build());
        if (!resultList.isSuccess()) {
            return Result.fail("OTS-02-003-01-16-025", ErrorMessage.code("OTS-02-003-01-16-025", null).getDisplayErrorMessage());
        }
        if (CollectionUtils.isNotEmpty(resultList.getResult())) {
            return Result.fail("OTS-02-003-01-16-035", ErrorMessage.code("OTS-02-003-01-16-035", null).getDisplayErrorMessage());
        }
        return Result.success(true);
    }
}
